package ks.client.lobby;

import javax.swing.JOptionPane;
import javax.swing.JFrame;
import javax.swing.WindowConstants;

import ks.client.gui.login.LoginGUI;
import ks.client.gui.plugin.PMGUI;


import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import ks.client.UserContext;
import ks.client.controllers.commands.IconListCommandController;
import ks.client.gui.GMGUI;
import ks.client.gui.GMTOPT;
import ks.client.gui.TMGUI;
import ks.client.gui.UMGUI3;
import ks.client.gui.UMGUI3CHAT;
import ks.client.gui.admin.AdminControlGUI;
import ks.client.gui.admin.plugin.PluginAdminGUI;
import ks.client.gui.user.AccountUpdateGUI;
import ks.client.ipc.Client;
import ks.client.kommander.Kommander;
import ks.client.processor.Processor;
import ks.framework.interfaces.IConnectionHandler;

/**
 * Primary KS client frontEnd that acts as the central hub for much of the
 * client-side behavior.
 * <p>
 * From the lobby you can always get the UserContext.
 * <p>
 * @author George Heineman
 */
public class Lobby extends JFrame implements IConnectionHandler {
	// keep eclipse happy
	private static final long serialVersionUID = 1L;

	// my GUI
	RoomGUI inner;
	LoginGUI loginGUI;

	/** User context for connection information. */
	UserContext context;
	
	Kommander kommander;
	
	

	/**
	 * Each lobby must have a context in which to operate.
	 */
	public Lobby(UserContext context) {
		this.context = context;
		
		kommander = new Kommander();
		
		// prepare 
		initialize();
	}

	/**new GMGUI(ClientArchitecture.solo, 7);
	 * Return the user context for this lobby.
	 */
	public UserContext getUserContext() {
		return context;
	}
	
	/**
	 * Initialize GUI elements of this component.
	 */
	private void initialize() {
		loginGUI = new LoginGUI(this);
		setContentPane(loginGUI);
		setTitle("Kombat Solitaire - Cyborg Edition");
		setSize(850, 750);

		setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

		addWindowListener(new WindowAdapter() {

			@Override
			public void windowOpened(WindowEvent we) {
				if (context == null) {
					System.err.println("Lobby must have a configured UserContext object.");
					setVisible (false);
					dispose();
				}
			}
			
			@Override
			public void windowClosing(WindowEvent we) {

				int selection = JOptionPane.showConfirmDialog(null,
						"Are you sure you want exit?", "Kombat Solitaire",
						JOptionPane.YES_NO_OPTION,
						JOptionPane.WARNING_MESSAGE);
				if( selection == JOptionPane.YES_OPTION ) {
					tryToDisconnect();
					setVisible(false);
					dispose();
				} else {
					inner.append("Thank goodness you came to your senses!");
				}
			}
		});
		
	}
	
	public Kommander getKommander() {
		return kommander;
	}
	
	public LoginGUI getLoginGUI() {
		return this.loginGUI;
	}
	
	public void newGMGUI(int table) {
		inner.newGameManagerGUI(table);
	}

	/**
	 * Respond to changes in our connected status
	 * 
	 * @param status
	 */
	public void connected(boolean status) {
		//inner.getLobbyOutput().setEditable(status);

		if (status) {
			inner = new RoomGUI(this);
			this.setContentPane(inner);
		}
		else {
			this.setContentPane(loginGUI);
			loginGUI.setFieldsEnabled(true);
			inner = null;
		}
		this.repaint();
		this.validate();
	}

	/**
	 * Try to disconnect from remote server.
	 * <p>
	 * If client not yet connected (because client is null) then return true
	 * since that is ok.
	 */
	public boolean tryToDisconnect() {
		Client client = context.getClient();
		if (client == null) { return true; }
		
		if (!client.disconnect()) {
			return false;
		}

		//inner.resetLogin();

		return true;
	}

	/** May need to expose inner GUI elements during testing. */
	public RoomGUI getRoom() {
		return inner;
	}
	/**Enable access to game manager GUI .*/
	public GMGUI getGMGUI(int num){
		return inner.getGameManagerGUI(num);
	}
	
	public GMGUI getGMGUI(){
		return inner.getGameManagerGUI();
	}
	
	/** Enable access to the user manager GUI. */
	public UMGUI3 getUMGUI3() {
		return inner.getUserManagerGUI();
	}
	
	/** Enable access to the plugin manager GUI. */
	public PMGUI getPMGUI() {
		return inner.getPluginManagerGUI();
	}
	
	/** Enable access to the table manager GUI. */
	public TMGUI getTMGUI() {
		return inner.getTableManagerGUI();
	}
	public UMGUI3CHAT getUMGUI3CHAT(){
		return inner.getUserManagerGUIchat();
	}
	
	/**Enable access to the Game Manager Table Options Gui */
	public GMTOPT getGMTOPT(int num){
		return inner.getGameManagerOptionsGUI(num);
	}
	
	/** Enable access to the plugin admin GUI. */
	public PluginAdminGUI getPluginAdminGUI(){
		return inner.getPluginAdminGUI();
	}
	
	/** Enable access to the account update GUI. */
	public AccountUpdateGUI getAccountUpdateGUI(){
		return inner.getAccountUpdateGUI();
	}
	
	/** Enable access to the admin control GUI. */
	public AdminControlGUI getAdminControlGUI(){
		return inner.getAdminControlGUI();
	}
	
	/**
	 * Append string to RoomGUI output.
	 * 
	 * @param s
	 */
	public void append(String s) {
		// strange race conditions when windows are closing...
		// make sure we can at least be displayed.
		if (!isDisplayable()) { return ; } 
		
		// go ahead with the append.
		inner.append(s);
	}

}

